package com.pug.order.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSON;
import com.pug.order.dto.OrderMakeReqDTO;
import com.pug.order.dto.OrderMakeRespDTO;
import com.pug.order.mapper.OrderMapper;
import com.pug.order.po.OrderPO;
import com.pug.order.service.IOrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import xq.pug.common.exception.ServiceException;
import xq.pug.common.result.R;
import xq.pug.feign.dto.order.MakeOrder3ReqDTO;
import xq.pug.feign.dto.order.MakeOrder3RespDTO;
import xq.pug.feign.dto.order.MakeOrder4ReqDTO;
import xq.pug.feign.dto.order.MakeOrder4RespDTO;
import xq.pug.feign.dto.product.DedInventoryFeignReqDTO;
import xq.pug.feign.dto.user.DeductionFeignReqDTO;
import xq.pug.feign.dto.user.DeductionFeignRespDTO;
import xq.pug.feign.dto.user.UserFeignReqDTO;
import xq.pug.feign.dto.user.UserFeignRespDTO;
import xq.pug.feign.service.product.InventoryServiceFeign;
import xq.pug.feign.service.user.UserServiceFeign;

import java.math.BigDecimal;
import java.util.Objects;

/**
 * @program: xq_pug_alibabacloud_parent
 * @description:
 * @author: Mr.Ren
 * @create: 2023-04-16 15:58
 **/
@Service
@Slf4j
public class OrderServiceImpl implements IOrderService {

    @Autowired
    private UserServiceFeign userServiceFeign;

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private InventoryServiceFeign inventoryServiceFeign;


    @Override
    public MakeOrder3RespDTO makeOrder3(MakeOrder3ReqDTO reqDTO) {

        UserFeignReqDTO userFeignReqDTO = new UserFeignReqDTO();
        userFeignReqDTO.setUserCode(reqDTO.getUserCode());
        R<UserFeignRespDTO> userResult = userServiceFeign.queryUser(userFeignReqDTO);
        if (userResult.isFail()) {
            throw new NullPointerException();
        }
        UserFeignRespDTO user = userResult.getData();

        String orderNo = IdUtil.fastSimpleUUID();
        log.info("订单号为：{}", orderNo);

        OrderPO orderPO = new OrderPO();
        orderPO.setOrderNo(orderNo);
        orderPO.setUserCode(user.getUserCode());
        orderPO.setProductCode("CO3622");
        orderPO.setOrderAmount(new BigDecimal("129.5"));
        orderMapper.saveOrder(orderPO);
        log.info("订单入库成功，相关参数：【{}】", JSON.toJSONString(orderPO));

        MakeOrder3RespDTO orderRespDTO = BeanUtil.copyProperties(user, MakeOrder3RespDTO.class);
        orderRespDTO.setOrderNo(orderNo);
        return orderRespDTO;

    }

    @Override
//    @Transactional(rollbackFor = Exception.class)
//    @GlobalTransactional(rollbackFor = Exception.class)
    public MakeOrder4RespDTO makeOrder4(MakeOrder4ReqDTO order) {

        //下单
        String orderNo = IdUtil.fastSimpleUUID();
        OrderPO orderPO = new OrderPO();
        orderPO.setOrderNo(orderNo);
        orderPO.setUserCode(order.getUserCode());
        orderPO.setProductCode(order.getProductCode());
        orderPO.setOrderAmount(order.getOrderAmount());
        orderMapper.saveOrder(orderPO);
        log.info("订单入库成功，相关参数：【{}】", JSON.toJSONString(orderPO));

        //扣库存
        DedInventoryFeignReqDTO dedInventoryFeignReqDTO = new DedInventoryFeignReqDTO();
        dedInventoryFeignReqDTO.setProductCode(order.getProductCode());
        dedInventoryFeignReqDTO.setDedCount(1);
        R<Integer> integerR = inventoryServiceFeign.dedInventory(dedInventoryFeignReqDTO);
        if (integerR.isFail()) {
            log.error("商品编号：{}，远程扣减库存失败", order.getProductCode());
            return null;
        }
        log.info("商品编号：{}，远程扣减库存成功", order.getProductCode());

        MakeOrder4RespDTO makeOrder4RespDTO = new MakeOrder4RespDTO();
        makeOrder4RespDTO.setOrderNo(orderNo);
        makeOrder4RespDTO.setUserName(order.getUserCode());
        makeOrder4RespDTO.setProductCode(order.getProductCode());
        makeOrder4RespDTO.setUserCode(order.getUserCode());
        if (Objects.equals(order.getProductCode(), "SZW870")) {
            log.error("下单发生异常，数据入库回滚");
            throw new RuntimeException();
        }

        return makeOrder4RespDTO;
    }


    @Override
    @Transactional
    public int saveOrder(MakeOrder4ReqDTO order) {
        //下单
        String orderNo = IdUtil.fastSimpleUUID();
        log.info("订单号为：{}", orderNo);

        OrderPO orderPO = new OrderPO();
        orderPO.setOrderNo(orderNo);
        orderPO.setUserCode(order.getUserCode());
        orderPO.setProductCode(order.getProductCode());
        orderPO.setOrderAmount(order.getOrderAmount());
        int i = orderMapper.saveOrder(orderPO);
        log.info("订单入库成功，相关参数：【{}】", JSON.toJSONString(orderPO));
        System.out.println(1 / 0);
        return i;

    }

    @Override
    public int insertOrder(MakeOrder4ReqDTO order) {
        int i = this.saveOrder(order);

        return i;
    }


    /**
     * 下单接口，供业务层远程调用
     * 内部调用用户服务扣款
     *
     * @param reqDTO
     * @return
     */
    @Override
    public OrderMakeRespDTO orderMake(OrderMakeReqDTO reqDTO) {

        String orderNo = IdUtil.fastSimpleUUID();

        BigDecimal totalPrice = reqDTO.getPrice().multiply(new BigDecimal(reqDTO.getNum()));
        //下单
        OrderPO orderPO = new OrderPO();
        orderPO.setOrderNo(orderNo);
        orderPO.setUserCode(reqDTO.getUserCode());
        orderPO.setProductCode(reqDTO.getProductCode());
        orderPO.setOrderAmount(totalPrice);
        int i = orderMapper.saveOrder(orderPO);
        if (i > 0) {
            log.info("订单入库成功，相关参数：【{}】", JSON.toJSONString(orderPO));
        } else {
            throw new ServiceException("订单入库失败");
        }

        //扣款
        DeductionFeignReqDTO deductionFeignReqDTO = BeanUtil.copyProperties(reqDTO, DeductionFeignReqDTO.class);
        R<DeductionFeignRespDTO> deductionResult = userServiceFeign.deduction(deductionFeignReqDTO);
        if (deductionResult.isFail()) {
            log.error("扣款失败");
            throw new ServiceException(deductionResult.getMessage());
        }

        //封装返回结果
        OrderMakeRespDTO orderMakeRespDTO = new OrderMakeRespDTO();
        orderMakeRespDTO.setConsumerPrice(totalPrice);
        orderMakeRespDTO.setUserCode(reqDTO.getUserCode());
        orderMakeRespDTO.setProductCode(reqDTO.getProductCode());
        return orderMakeRespDTO;
    }
}
